/**
 * created by dt at 2025/5/4
 */

type EventHandler<T extends Event> = (event: T) => void;

export class Event {
}

export class EventBus {
    private _eventHandlers = new Map<new (...args: any[]) => Event, Set<EventHandler<any>>>();
    // 使用一个常驻的临时数组来避免重复创建
    private _tempHandlers: EventHandler<any>[] = [];

    /**
     * Register an event listener for a specific event type
     * @param eventType The event class to listen for
     * @param handler The callback function to handle the event
     */
    public on<T extends Event>(eventType: new (...args: any[]) => T, handler: EventHandler<T>): void {
        if (!this._eventHandlers.has(eventType)) {
            this._eventHandlers.set(eventType, new Set());
        }
        this._eventHandlers.get(eventType)!.add(handler);
    }

    /**
     * Remove an event listener for a specific event type
     * @param eventType The event class to remove listener from
     * @param handler The callback function to remove
     */
    public off<T extends Event>(eventType: new (...args: any[]) => T, handler: EventHandler<T>): void {
        const handlers = this._eventHandlers.get(eventType);
        if (handlers) {
            handlers.delete(handler);
            if (handlers.size === 0) {
                this._eventHandlers.delete(eventType);
            }
        }
    }

    /**
     * Trigger an event and notify all registered listeners
     * @param event The event to trigger
     */
    public triggerEvent<T extends Event>(event: T): void {
        const handlers = this._eventHandlers.get(event.constructor as new (...args: any[]) => T);
        if (handlers) {
            // 清空临时数组
            this._tempHandlers.length = 0;
            // 将 Set 中的处理器复制到临时数组
            handlers.forEach(handler => this._tempHandlers.push(handler));
            // 使用临时数组遍历调用处理器
            for (let i = 0; i < this._tempHandlers.length; i++) {
                this._tempHandlers[i](event);
            }
        }
    }

    /**
     * Clear all event listeners for a specific type
     * @param eventType The event class to clear
     */
    public clear(eventType?: new (...args: any[]) => Event): void {
        if (eventType) {
            this._eventHandlers.delete(eventType);
        } else {
            this._eventHandlers.clear();
        }
    }
} 